#include "custom.h"
std::vector<variable> local_parse(std::string input) {
    local_parser psr(input);
    psr.local_parse();
    return psr.get_variables();
}
char local_parser::advance() {
    current++;
    return input[current - 1];
}
char local_parser::peek() {
    if (isEnd()) {
        return '\0';
    }
    return input[current];
}
bool local_parser::isEnd() {
    return current >= input.length();
}

local_parser::local_parser(std::string input):input(input), current(0) {}

void local_parser::local_parse() {
    char c = peek();
    while(c != '\0') {
        if(c != '<') {
            throw std::string("except variable definition");
        }
        parse_one_variable();
        c = peek();
    }
}

void local_parser::parse_one_variable() {
    advance();
    std::string name = take_varname();
    if(peek() != '>') {
        std::cerr << name << std::endl;
        throw std::string("except >");
    }
    advance();
    if(peek() != '=') {
        throw std::string("except initial value");
    }
    advance();
    int value = take_number();
    variables.push_back(variable(name, tokentype::NUMBER, value));
}
std::vector<variable> local_parser::get_variables() {
    return variables;
}
std::string local_parser::take_varname() {
    char c = peek();
    std::string varname = "";
    while((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9')) {
        varname += advance();
        c = peek();
    }
    return varname;
}

std::string local_parser::residu() {
    std::string ret;
    while(!isEnd()) {
        ret += advance();
    }
    return ret;
}

int local_parser::take_number() {
    std::string numberstr = "";
    int number;

    char c = peek();
    if (c != '-' && (c < '0' || c > '9')) {
        std::cerr << c << std::endl;
        throw std::string("not a number [") + residu() + "]";
    }
    numberstr += advance();
    c = peek();
    while(c >= '0' && c <= '9') {
        numberstr += advance(); 
        c = peek();
    }
    std::stringstream temp(numberstr);
    temp >> number;
    return number;
}
